// Copyright(c) Sonosemi Medical Ltd. Embedded Software Team.
// Author: Zhang Yisong(zhangyisong@sonosemi.com)

#pragma once
#include "error_code.hpp"
namespace zpp {

/// @brief Represents an error with an associated error code.
class error {
public:
  /// @brief Constructs an error object with the given error code.
  /// @param code The error code represented as an `error_code` enumeration
  /// value.
  error(error_code code) : m_code(code) {}

  /// @brief Constructs an error object with the given integer error code.
  /// @param code The error code represented as an integer, which will be cast
  /// to `error_code`.
  error(int code) {
    if (code < 0) {
      code = -code;
    }
    m_code = static_cast<error_code>(code);
  }

  /// @brief Converts the error object to a boolean value.
  /// @return `true` if the error code is `error_code::k_ok`, indicating no
  /// error; `false` otherwise.
  operator bool() const { return m_code == error_code::k_ok; }

  /// @brief Gets the error code stored in the error object.
  /// @return The error code of type `error_code`.
  error_code code() const { return m_code; }

  /// @brief Checks if the error object represents no error.
  /// @return Returns `true` if the error code is `error_code::k_ok`, indicating
  /// no error;
  ///         `false` otherwise.
  auto ok() -> bool const { return m_code == error_code::k_ok; }
  /// @brief Gets the string representation of the error code.
  /// @return A pointer to a constant C-style string describing the error.
  auto str() -> const char * { return error_str(m_code); }

  auto operator=(const error &other) -> error & {
    m_code = other.m_code;
    return *this;
  }
  auto operator=(const error &&other) -> error & {
    m_code = other.m_code;
    return *this;
  }

  error(const error &&err) : m_code(err.m_code) {}

  error(const error &err) : m_code(err.m_code) {}

private:
  error_code m_code;
};

/// Return the error class initialized with error_code::k_ok
inline auto ok() -> error { return error{0}; }

/// Check the returned retults that are errnos from functions provided by zephyr
/// RTOS
inline auto check_error(int res) -> error { return error{-res}; }

#define ZPP_TRY(error) ZPP_ERROR_TRY(error)

} // namespace zpp
